#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

#include "nstar_front_panel.h"
#include "nstar_hcf4051.h"
#include "app_delay.h"


static volatile long panel_sta_timer;
#define FRONT_STA_SLEEP(n) app_sleep(&panel_sta_timer, n*1000)
#define FRONT_STA_PEND(n) app_pend_wake(panel_sta_timer)

static volatile long panel_uabsta_timer;
#define FRONT_USBSTA_SLEEP(n) app_sleep(&panel_uabsta_timer, n*1000)
#define FRONT_USBSTA_PEND(n) app_pend_wake(panel_uabsta_timer)





static volatile unsigned char flg_sta = 0;

enum msg_head{
	MSG_HEAD_STA= 0x01,			//状态
	MSG_HEAD_PARM= 0x02,		//参数
	MSG_HEAD_FIRMWARE= 0x03,	//从机升级固件
	MSG_HEAD_MP3= 0x04,			//MP3类信息或参数
	MSG_HEAD_MAX,
};
/*面板发往主板的MP3控制*/

enum STBPARM_TYPE{
	STBPARM_LOCAL_IP=0,
	STBPARM_REMOTE_IP,
	STBPARM_GATEWAY,
	STBPARM_MASK,
	STBPARM_LOACL_PORT,
	STBPARM_REMOTE_PORT,
	STBPARM_CH_SEL,
	STBPARM_Logicaddr,		/*7.逻辑地址*/
	STBPARM_LockFeqAddr,	/*8.锁频地址*/
	STBPARM_CtlPID, 		/*9.指令PID*/
	STBPARM_PNUM,			/*10.节目号*/
	STBPARM_VOLUME, 		/*11.音量*/
	STBPARM_EncodeMode, 	/*12.编码方式*/
	STBPARM_PType,			/*13.节目版本*/
	STBPARM_AudioPID,		/*14.音频PID*/
	STBPARM_PSip,			/*15.节目源IP*/
	STBPARM_PSport, 		/*16.节目源端口*/
    STBPARM_HEART_TIMEOUT_PERIOD,	/*17.未受控超时重启时间 单位小时，其中0：不重启*/
	STBPARM_FM_POWER,
    STBPARM_FM_FQ,
	STBPARM_FM_AUTOSCAN,

	STBPARM_RecoverBak = 0x80, 	/*0x80.恢复出厂*/
	STBPARM_SYNC_REQ,		/*0x81.面板网络参数请求*/
	STBPARM_Audio_SYNC_REQ, /*0x82.面板音频参数请求*/
	STBPARM_PARM_MAX,
};

enum QUEUE_TYPE{
	QUEUE_TYPE_SND,
	QUEUE_TYPE_PLAY_STATUS,
};
struct _front_panel{
#define FRONT_PANEL_LEN_MAX 255
	unsigned char status;
	unsigned char playStatus;
	unsigned char dta[FRONT_PANEL_LEN_MAX];
    void(*p_callback)(void);
	unsigned int len;
};
enum SEL_TYPE{
	SEL_NONE=0,
	SEL_MIC=1,
	SEL_USB,
	SEL_LINE1,
	SEL_LINE2,
	SEL_RESERVE,
};



void nstar_front_setflg(void) {
    flg_sta = 1;
}

static void _param_sel(unsigned char*p_dta,unsigned int len)
{
    enum{
		OLD_SEL_NONE=0,
		OLD_SEL_MIC=1,
		OLD_SEL_USB,
		OLD_SEL_LINE1,
		OLD_SEL_LINE2,
		OLD_SEL_PanelMP3,
		OLD_SEL_RESERVE
	};
        
    struct ch_sel_info{
		unsigned char ch_nb:7;
		unsigned char emergency_sta:1;
	};
    if(len == 1){
        struct ch_sel_info *sel= (struct ch_sel_info*)p_dta;
        switch(sel->ch_nb){
            case OLD_SEL_PanelMP3:
                PANEL_SEL_MP3(sel->emergency_sta);
                break;
            case OLD_SEL_MIC:
                PANEL_SEL_MIC(sel->emergency_sta);
                break;
            case OLD_SEL_LINE1:
                PANEL_SEL_LINE1(sel->emergency_sta);
                break;
            case OLD_SEL_LINE2:
                PANEL_SEL_LINE2(sel->emergency_sta);
                break;
            default:
                PANEL_SEL_NONE();
                break;
        }
        nstar_front_setflg();
	}
}

#define _FRONT_QUEUE_SND _front_send
#define _FRONT_QUEUE_REC _front_rec

static int front_fd = -1;
static int _front_send(unsigned char *buf, unsigned int len) {
    return write(front_fd, buf, len);
}

static int _front_rec(unsigned char *buf, unsigned int len) {
    return read(front_fd, buf, len);
}


int nstar_front_panel_init(void) 
{
#define DEV_PATH "/dev/nstar_lcd"
    int fd_d = open(DEV_PATH, O_SYNC | O_RDWR);
    if(fd_d < 0) {
        printf("panel init faild\n");
        return -1;
    }
    front_fd =  fd_d;
    printf("panel init ok %d\n", front_fd);
    return 0;
}


 void _sync_req_u32(unsigned char tye,unsigned int dtaU32)
{
	unsigned char syncReq[6]= {MSG_HEAD_PARM,tye};
	syncReq[5] = (dtaU32>>24)&0xff;
	syncReq[4] = (dtaU32>>16)&0xff;
	syncReq[3] = (dtaU32>>8)&0xff;
	syncReq[2] = (dtaU32)&0xff;
	_FRONT_QUEUE_SND(syncReq,6);
}
 void _sync_req_u16(unsigned char tye,unsigned short dtaU16)
{
	unsigned char syncReq[4]= {MSG_HEAD_PARM,tye};
	syncReq[2] = (dtaU16)&0xff;
	syncReq[3] = (dtaU16>>8)&0xff;
	_FRONT_QUEUE_SND(syncReq,4);
}
 void _sync_req_u8(unsigned char tye,unsigned char dtaU8)
{
	unsigned char syncReq[3]= {MSG_HEAD_PARM,tye};
	syncReq[2] = dtaU8;
	_FRONT_QUEUE_SND(syncReq,3);
}
 void _sync_req_str(unsigned char tye,unsigned char *p_dta,unsigned char len)
{
#define SYNC_REQ_STR_MAX 30
	unsigned char syncReq[SYNC_REQ_STR_MAX]= {MSG_HEAD_PARM,tye};
	if(len + 2 < SYNC_REQ_STR_MAX){
		memcpy(&syncReq[2],p_dta,len);
		_FRONT_QUEUE_SND(syncReq,len+2);
	}
	else{
		printf(" _sync_req_str len:%d err!",len);
	}
}

 void _param_sync_req(unsigned char*p_dta,unsigned int len)
{
	if(len == 0){
		_sync_req_u32(STBPARM_LOCAL_IP, 192 >> 24  );
	}
}

static void _parse_param(unsigned char*p_dta,unsigned int len)
{
	if(len > 0){
		p_dta++;
		len--;
		switch(p_dta[-1]){
		case STBPARM_CH_SEL:		
            _param_sel(p_dta, len);            
            break;       
		default:
			break;
		}

	}
}


static void _parse_dta(unsigned char*p_dta,unsigned int len)
{
    p_dta++;
	len --;
	switch(p_dta[-1]){
		case MSG_HEAD_PARM:
			_parse_param(p_dta,len);
			break;	   
		default:
			break;
	}
}

static unsigned char sel_convert_to_ledsta(void)
{

    /*
0x0： "待机",
0x01："受控（上级）IP广播",
0x02："受控（上级）-T广播",
0x03："受控（上级）-C广播",
0x04："受控（上级）调频广播",
0x05："受控（上级）4G广播",
0x80： "本地U盘",
0x81： "本地话筒",
0x82： "本地线路1", 
0x83： "本地线路2",
0x84： "本地对讲",
其他：未定义广播
*/

    unsigned char sel= visit_ch_sel();
    switch(sel){
        case CH_NB_MAX:
            sel= 0;
            break;
        case CH1_NB_MP3:  
        case CH1_NB_MIC:
        case CH1_NB_LINE1:
        case CH1_NB_LINE2:
            sel-=2;
            sel|=0x80;
            break;   
        case CH1_NB_INTERPHONE:
            sel=0x84;
            break;  
       case CH1_NB_DVB:

            sel = 0x1;
          
            break; 
        default:  
            sel= 0xff;
            break;
    }
    return sel;
}



static void nstar_front_panel_status_set(void)
{
    typedef struct STBSTA{
        unsigned char head; 
        unsigned char work_sta;       /*0：受控正常(弃用)，1：异常，2：IP受控，3：-T， 4：-C, 5：调频，6：4G，7:对讲
                                        0x83 -T搜台  ， 0x84 -C搜台*/  
        unsigned char stb_connect_sta;/*0.编码器未连接，1.编码器连接 2 说明是编码适配器*/
        unsigned char box_vol_sel;    /*机顶盒音源(弃用)*/
        unsigned char work_mode_1u;   /*广播状态 0：待机，1：日常 2: 应急*/
        unsigned char ch_sel_1u;        /*广播通道：
                                        0x0： "待机",
                                        0x01："受控（上级）IP广播",
                                        0x02："受控（上级）-T广播",
                                        0x03："受控（上级）-C广播",
                                        0x04："受控（上级）调频广播",
                                        0x05："受控（上级）4G广播",
                                        0x80： "本地U盘",
                                        0x81： "本地话筒",
                                        0x82： "本地线路1", 
                                        0x83： "本地线路2",
                                        0x84： "本地对讲",
                                        其他：未定义广播
                                        */   
        unsigned char work_sta_str[8];       
    }__attribute__ ((packed))STBSTA_TYPE;
#define STBSTA_TYPE_SIZE (sizeof(STBSTA_TYPE))
    unsigned char buf[STBSTA_TYPE_SIZE]={0};
    STBSTA_TYPE *sta= (STBSTA_TYPE*)buf;
    sta->head= MSG_HEAD_STA;
    sta->stb_connect_sta= 0;
    //sta->work_sta= visit_command_net_sta2() ? 2 : 1;
    sta->work_sta = 2;
    sta->work_mode_1u= visit_ch_eflag();
    sta->ch_sel_1u= sel_convert_to_ledsta();
    
    sta->work_sta_str[5]= 20;
    if(sta->work_mode_1u == 1 || sta->work_mode_1u == 2){
        unsigned int speed= 1000;
        sta->work_sta_str[0]= (speed >> 8)&0xff;
        sta->work_sta_str[1]= speed&0xff;
        speed= 0;
        sta->work_sta_str[2]= (speed >> 16)&0xff;
        sta->work_sta_str[3]= (speed >> 8)&0xff;
        sta->work_sta_str[4]= speed&0xff;
        
    }else {
       
    }
	_FRONT_QUEUE_SND(buf,STBSTA_TYPE_SIZE);

}


void nstar_front_loop(void)
{
    //if(FRONT_USBSTA_PEND())
    {  
    	if(front_fd >= 0){
            int len;
            unsigned char buf[FRONT_PANEL_LEN_MAX];
    		len = _front_rec(buf,FRONT_PANEL_LEN_MAX);
    		if(len > 0 ){
                myarray(buf, len);
    			_parse_dta(buf, len);
    		}       
            if(FRONT_STA_PEND() || flg_sta){ 
                flg_sta = 0;
    			nstar_front_panel_status_set();
    			FRONT_STA_SLEEP(3);   
    		}
    	}
        FRONT_USBSTA_SLEEP(1);
    }
}











